<script setup lang="ts">
import { computed, reactive, ref, watch } from 'vue'
import { getRandom, shuffleArray } from '@/utils'
import GlassBlock from '@/components/glass-block.vue'
import CubeBlock from '@/components/cube-block.vue'

const props = defineProps<{
  answerList: string[]
  puzzleList: string[]
}>()

const emits = defineEmits(['success', 'advance'])

const correctList = reactive<number[]>([])
const cubeHeight = computed(() =>
  props.answerList.length === 0 ?
    '0vh'
  : `${(80 * correctList.length) / props.answerList.length}vh`
)

const puzzle = ref(0)
const answer = reactive<number[]>([puzzle.value])

const initAnswer = () => {
  answer.splice(0)
  answer.push(puzzle.value)
  for (let i = 0; i < 3; i++) {
    answer.push(getRandom(props.answerList.length, answer))
  }
  shuffleArray(answer)
}

initAnswer()
watch(
  computed(() => props.answerList),
  () => initAnswer()
)

const refresh = () => {
  puzzle.value++
  answer.splice(0)
  answer.push(puzzle.value)
  for (let i = 0; i < 3; i++) {
    answer.push(getRandom(props.answerList.length, answer))
  }
  shuffleArray(answer)
}

const choose = (e: Event) => {
  const dom = e!.target as HTMLInputElement
  if (dom.checked) {
    if (
      props.answerList[parseInt(dom.value)] === props.answerList[puzzle.value]
    ) {
      correctList.push(puzzle.value)

      setTimeout(() => {
        dom.checked = false
        emits('advance')

        if (correctList.length === props.puzzleList.length) {
          emits('success')
          correctList.splice(0)
        }
        refresh()
      }, 200)
    }
  }
}
</script>

<template>
  <GlassBlock class="board">
    <GlassBlock class="puzzle text">
      {{ props.puzzleList[puzzle] }}
    </GlassBlock>
    <div class="choice">
      <GlassBlock class="item text" v-for="(v, i) in answer" :key="i">
        <label>
          <input
            :class="v === puzzle ? 'sucess' : 'error'"
            type="radio"
            name="choice"
            :value="v"
            @change="choose"
          />
          <div class="text">{{ props.answerList[v] }}</div>
        </label>
      </GlassBlock>
    </div>
  </GlassBlock>

  <CubeBlock
    class="cube"
    :width="'100%'"
    :height="cubeHeight"
    :depth="'100px'"
    :border="false"
  >
    <template #front>
      <div class="face front"></div>
    </template>
    <template #back>
      <div class="face back"></div>
    </template>
    <template #left>
      <div class="face left"></div>
    </template>
    <template #right>
      <div class="face right"></div>
    </template>
    <template #top>
      <div class="face top"></div>
    </template>
    <template #bottom>
      <div class="face bottom"></div>
    </template>
  </CubeBlock>
</template>

<style>
.board {
  position: relative;
  width: 100%;
  min-height: 80vh;
  max-height: 100vh;
  font-family: 'Georgia', Times, 'Times New Roman', serif;
  font-size: 1.5rem;

  display: grid;
  grid-template-rows: 2fr 4fr;
  place-content: center;
}

.cube {
  position: relative;
  bottom: v-bind(cubeHeight);
  transform: rotateX(-10deg) rotateY(10deg);
  z-index: -1;
}

.face {
  width: 100%;
  height: 100%;
  position: inherit;
  opacity: 0.9;
}

.front {
  background: linear-gradient(45deg, #40e0d0, #ff8c00);
}

.bottom {
  background: linear-gradient(45deg, #008000, #ffff00);
}

.top {
  background: linear-gradient(45deg, #ff4e50, #f9d423);
}

.left {
  background: linear-gradient(45deg, #00ffff, #ff0000);
}

.puzzle {
  position: relative;
  width: 80vw;
  height: 15vh;
  place-self: center;
}

.choice {
  display: grid;
  grid-template-rows: repeat(4, 1fr);
  place-items: center;
}

.choice .item {
  position: relative;
  width: 60vw;
  height: 8vh;
}

.choice .item input {
  display: none;
}

.choice .item input.error:checked + .text {
  color: #ef4149;
  text-shadow: 0 0 30px #ef4149;
  transform: scale(0.85);
  transition: all 0.5s;
}

.choice .item input.sucess:checked + .text {
  color: #67c23a;
  text-shadow: 0 0 30px #67c23a;
  transform: scale(0.85);
  transition: all 0.5s;
}

.text {
  text-align: center;
  align-content: center;
}

@media screen and (min-width: 768px) {
  .board {
    width: 40vw;
    margin-left: 20vw;
  }

  .cube {
    margin-left: 20vw;
  }

  .puzzle {
    width: 30vw;
  }

  .choice .item {
    width: 20vw;
  }
}
</style>
